home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
bteasy14.zip
/
BOOTINST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-11
|
8KB
|
256 lines
/*
* Boot installator.
* Author: Serge Vakulenko, <vak@kiae.su>
*/
#include <stdio.h>
#include <fcntl.h>
#include <dos.h>
#define BOOTFILE "boot.bin"
#define SAVEFILE "bootsav.bin"
#define SAVE2FILE "boot2sav.bin"
#define PartAddr 0x1be /* Offset to partition table */
#define ValidationAddr 0x1fe /* Offset to validation bytes */
#define MAGIC 0xaa55 /* Validation tag */
#define DISK1 0
#define DISK2 1
#define READ 0
#define WRITE 1
typedef struct PartitionEntry {
unsigned char bootIndicator;
unsigned char beginHead;
unsigned char beginSector;
unsigned char beginCyl;
unsigned char systemId;
unsigned char endHead;
unsigned char endSector;
unsigned char endCyl;
unsigned short relSectorLow;
unsigned short relSectorHigh;
unsigned short numSectorsLow;
unsigned short numSectorsHigh;
} PartitionEntry;
unsigned char bootRecord [512];
unsigned char bootProg [512];
yes ()
{
char reply [80];
printf (" (yes/no) ");
fgets (reply, sizeof (reply), stdin);
return (!stricmp (reply, "y\n") || !stricmp (reply, "yes\n"));
}
main (argc, argv)
char **argv;
{
char *bootfile;
int disk2present;
printf ("Boot installer, version 1.4, Copyright (C) Serge Vakulenko\n\n");
printf ("This utility allows you to install new boot program on your\n");
printf ("hard disk. The usage is:\n\n");
printf (" bootinst [bootfile]\n\n");
printf ("It installs boot block from bootfile (default boot.bin) to the first\n");
printf ("drive and, if second drive is present, to the second drive.\n");
printf ("Old boot sectors are saved to bootsav.bin and boot2sav.bin respectively.\n");
printf ("\nYou can copy and distribute this software free of charge,\n");
printf ("provided that sources are included. No warranty, of course.\n\n");
if (argc > 3)
return (-1);
bootfile = argc>1 ? argv[1] : BOOTFILE;
if (access (bootfile, 4) < 0) {
perror (bootfile);
return (-1);
}
/*
* Is second disk present? Try to read boot sector,
* check that it is bootable and has valid partition table.
*/
disk2present = (bootio (DISK2, READ, 0, 0, 1, bootRecord) == 0 &&
*(short *) &bootRecord [ValidationAddr] == (short) MAGIC &&
(bootRecord [PartAddr] == 0 || bootRecord [PartAddr] == 0x80) &&
(bootRecord [PartAddr+16] == 0 || bootRecord [PartAddr+16] == 0x80) &&
(bootRecord [PartAddr+32] == 0 || bootRecord [PartAddr+32] == 0x80) &&
(bootRecord [PartAddr+48] == 0 || bootRecord [PartAddr+48] == 0x80));
printf ("Continue with installation?");
if (! yes ())
return (0);
install (DISK1, bootfile, SAVEFILE);
if (disk2present)
install (DISK2, bootfile, SAVE2FILE);
return (0);
}
install (disk, file, savefile)
char *file, *savefile;
{
int rc, fd;
rc = bootio (disk, READ, 0, 0, 1, bootRecord);
if (rc) {
fprintf (stderr, "Error %d reading boot record from disk %d\n",
rc, disk);
exit (-1);
}
if (*(short *) &bootRecord [ValidationAddr] != (short) MAGIC) {
fprintf (stderr, "Bad master boot record on disk %d!\n",
disk);
exit (-1);
}
printtable (disk);
fd = open (file, O_RDONLY|O_BINARY);
if (fd < 0) {
fprintf (stderr, "Cannot read file %s\n", file);
exit (-1);
}
if (read (fd, bootProg, 512) != 512) {
fprintf (stderr, "Error reading %s\n", file);
exit (-1);
}
close (fd);
if (*(short *) &bootProg [ValidationAddr] != (short) MAGIC) {
fprintf (stderr, "Bad boot image in file %s\n", file);
exit (-1);
}
printf ("\nAre you sure you want to install new boot on disk %d?",
disk);
if (! yes ())
exit (0);
close (creat (savefile, 0664));
fd = open (savefile, O_WRONLY|O_BINARY);
if (fd < 0) {
fprintf (stderr, "Cannot write to file %s\n", savefile);
exit (-1);
}
if (write (fd, bootRecord, 512) != 512) {
fprintf (stderr, "Error writing to %s\n", savefile);
exit (-1);
}
close (fd);
memcpy (bootRecord, bootProg, PartAddr);
rc = bootio (disk, WRITE, 0, 0, 1, bootRecord);
if (rc) {
fprintf (stderr, "Error %d updating boot record on disk %d\n",
rc, disk);
exit (-1);
}
printf ("New boot record successfully installed.\n");
}
bootio (disk, op, head, cyl, sect, buf)
char *buf;
{
return (biosdisk (op==WRITE ? 3 : 2, disk==DISK1 ? 0x80 : 0x81,
head, cyl, sect, 1, buf));
}
static char head1 [] = "┌─┬─────────┬────┬────┬───────────────┬───────────────┬─────────┬─────────┐\n";
static char head2 [] = "│ │Partition│Can │Boot│ Beginning │ Ending │ Relative│Number of│\n";
static char head3 [] = "│N│ Type │Boot│Part│Head Cyl Sect│Head Cyl Sect│ Sectors │ Sectors │\n";
static char head4 [] = "├─┼─────────┼────┼────┼────┬─────┬────┼────┬─────┬────┼─────────┼─────────┤\n";
static char mid1 [] = "│%d│%-9.9s│%-4.4s│%-4.4s│%3u │%4u │%3u │%3u │%4u │%3u │%8lu │%8lu │\n";
static char mid2 [] = "├─┼─────────┼────┼────┼────┼─────┼────┼────┼─────┼────┼─────────┼─────────┤\n";
static char foot [] = "└─┴─────────┴────┴────┴────┴─────┴────┴────┴─────┴────┴─────────┴─────────┘\n";
printtable (disk)
{
PartitionEntry *part = (PartitionEntry *) (bootRecord + PartAddr);
int i, cb;
long relSectors;
long numSectors;
char *typeString, block [512];
printf ("\n");
printf (head1);
printf (head2);
printf (head3);
printf (head4);
for (i=0; i<4; ++i) {
switch (part->systemId) {
default: typeString = " ?????"; cb = 1; break;
case 0: typeString = " empty"; cb = 0; break;
case 1: typeString = " dos-12"; cb = 1; break;
case 2: typeString = " xenix"; cb = 1; break;
case 3: typeString = "xenix usr"; cb = 0; break;
case 4: typeString = " dos-16"; cb = 1; break;
case 5: typeString = " extend"; cb = 0; break;
case 6: typeString = " bigdos"; cb = 1; break;
case 7: typeString = " hpfs"; cb = 1; break;
case 0x75: typeString = " pcix"; cb = 1; break;
case 0xdb: typeString = " cp/m"; cb = 1; break;
case 0xff: typeString = " bbt"; cb = 0; break;
case 0x08: typeString = " aix"; cb = 0; break;
case 0x09: typeString = " coherent"; cb = 1; break;
case 0x0A: typeString = " os/2"; cb = 1; break;
case 0x10: typeString = " opus"; cb = 1; break;
case 0x40: typeString = "venix 286"; cb = 1; break;
case 0x50:
case 0x51: typeString = " dm"; cb = 1; break;
case 0x52: typeString = "microport"; cb = 1; break;
case 0x56: typeString = " gb"; cb = 1; break;
case 0x61:
case 0xE1:
case 0xE3:
case 0xE4:
case 0xF1:
case 0xF4: typeString = " speed"; cb = 1; break;
case 0x63: typeString = " unix"; cb = 1; break;
case 0x64: typeString = "novell286"; cb = 1; break;
case 0x65: typeString = "novell386"; cb = 1; break;
case 0x80: typeString = "old minix"; cb = 1; break;
case 0x81: typeString = " minix"; cb = 1; break;
case 0x82: typeString = " linux"; cb = 1; break;
case 0x93: typeString = " amoeba"; cb = 1; break;
case 0x94: typeString = "amoebaBBT"; cb = 0; break;
case 0xA5: typeString = " 386bsd"; cb = 1; break;
case 0x9f:
case 0xB7: typeString = " bsdi"; cb = 1; break;
case 0xB8: typeString = "bsdi swap"; cb = 0; break;
case 0xF2: typeString = " dos sec"; cb = 1; break;
}
relSectors = part->relSectorLow |
(unsigned long) part->relSectorHigh<<16;
numSectors = part->numSectorsLow |
(unsigned long) part->numSectorsHigh<<16;
if (cb && (bootio (disk, READ, part->beginHead, part->beginCyl,
part->beginSector, block) != 0 ||
*(short *) &block [ValidationAddr] != (short) MAGIC))
cb = 0;
printf (mid1, i+1, typeString, cb ? " yes" : " no",
(part->bootIndicator & 0x80) ? " yes" : " no",
part->beginHead, part->beginCyl |
part->beginSector<<2 & 0x300,
part->beginSector & 077, part->endHead,
part->endCyl | part->endSector<<2 & 0x300,
part->endSector & 077, relSectors, numSectors);
if (i < 3)
printf (mid2);
++part;
}
printf (foot);
}